//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Graphics/GLshell/StateManager.h"
#include "Graphics/Systems/BatchRender.h"
#include "Graphics/Systems/Viewport.h"
#include "Graphics/Systems/Render.h"
#include "Graphics/Systems/ShaderManager.h"

// Loaders //
#include "Graphics/Loaders/TextureLoader.h"
#include "Graphics/Loaders/ModelLoader.h"
#include "Graphics/Loaders/FontLoader.h"
#include "Graphics/Loaders/ProgramLoader.h"
#include "Graphics/Loaders/SpriteLoader.h"


namespace Engine
{
namespace Graphics
{
	using namespace Base;


	//
	// Graphics Engine
	//

	class GraphicsEngine : public BaseObject
	{
	// types
	private:
		SHARED_POINTER( GraphicsEngine );


	// variables
	private:
		VideoSettings	_videoSettings;
		StateManager	_stateMngr;
		Viewport		_viewport;

		BatchRenderPtr	_currentBatchRender;
		ViewportPtr		_currentViewport;

		Render2D		_render2D;
		Render3D		_render3D;

		ShaderManager	_shaderMngr;

		ProgramLoader	_programLoader;
		TextureLoader	_textureLoader;
		FontLoader		_fontLoader;
		SpriteLoader	_spriteLoader;

		bool			_initialized;


	// methods
	public:
		GraphicsEngine (const EngineSubSystemsRef ess);
		~GraphicsEngine ();
		
		VideoSettings const &	GetVideoSettings ()	const	{ return _videoSettings; }
		
		StateManager *			GetStateManager ()			{ return &_stateMngr; }

		const BatchRenderPtr &	GetBatchRender ()	const	{ return _currentBatchRender; }
		const ViewportPtr &		GetViewport ()		const	{ return _currentViewport; }

		Render2D const &		GetRender2D ()		const	{ return _render2D; }
		Render3D const &		GetRender3D ()		const	{ return _render3D; }

		ShaderManager *			GetShaderManager ()			{ return &_shaderMngr; }

		TextureLoader *			GetTextureLoader ()			{ return &_textureLoader; }
		FontLoader *			GetFontLoader ()			{ return &_fontLoader; }
		ProgramLoader *			GetProgramLoader ()			{ return &_programLoader; }
		SpriteLoader *			GetSpriteLoader ()			{ return &_spriteLoader; }


		void SetBatchRender (const BatchRenderPtr &br)
		{
			_currentBatchRender = br;
		}

		void SetViewport (const ViewportPtr &vp)
		{
			_currentViewport = vp.IsNotNull() ? vp : &_viewport;
			_currentViewport->Apply();
		}

		void SwapBuffers ()
		{
			ESS()->GetApplication()->GetPlatform()->SwapBuffers();
		}

		bool Init (const VideoSettings &vs);
		void InitResources ();

	private:
		void _OnResized ();
		void _Destroy ();

		void _OnWindowEvent (const SysEvent &ev);
		void _OnApplicationEvent (const SysEvent &ev);
	};

}	// Graphics
}	// Engine